Control flow integrity aims to ensure the order in which individual statements, instructions, or function calls of a software program are executed or evaluated by a processor. A part of control flow integrity prevents calling of a modified pointer to indirect jump/branch targets, such as could occur from arbitrary modifications of function pointers, virtual function calls, and function returns. The prevention of arbitrary modification of indirect jump/branch targets uses static analysis (by a compiler or instrumentation) to build tables of the legitimate indirect jump/branch targets. At runtime, the tables are used to check whether an indirect jump/branch is to a valid target.
Such control flow integrity implementations have been shown to be insecure. To minimize runtime overhead, some runtime checks of the tables of the legitimate indirect jump/branch targets are removed or weakened. The control flow integrity also depends on static analysis to determine the legitimate jump/branch targets, which can result in incomplete identification of all legitimate jump/branch targets for a program. Thus, the tables are too coarse-grain, missing legitimate jump/branch targets and resulting in false negatives. The tables are also susceptible to attacks that swap pointers in the same table (e.g., pointers to read and write functions). A dynamic approach, such as cryptographic control flow integrity, can help address the susceptibility to attacks. However, such dynamic solutions incur much higher overhead, typically a 30% increase or a two times slow down in program execution.